package com.zam.web.courseController;

import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zam.comment.Result;
import com.zam.pojo.Course;
import com.zam.pojo.CourseUser;
import com.zam.service.ICourseService;
import com.zam.service.ICourseUserService;
import com.zam.service.UserService;
import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;

import static com.zam.comment.Constants.CODE_400;
import static com.zam.comment.Constants.COURSE_KEY;

/**
 * @Author talent_dog
 * @Date 2024/1/21 15:49
 * @Version 1.0
 */
@RestController
@RequestMapping("/HDFS")
public class HDFSController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    // 配置连接
    FileSystem fs = null;

    @Autowired
    private UserService userService;

    @Autowired
    private ICourseService iCourseService;

    @Autowired
    private ICourseUserService iCourseUserService;

    //上传
    @RequestMapping("/upload")
    public Result upload(@RequestParam MultipartFile file, HttpServletRequest request) throws Exception {
        if (file.isEmpty()) {
            return Result.error(CODE_400,"文件为空");
        }
        String originalFilename = file.getOriginalFilename();

        //连接hdfs
        initHDFS();

        //获取token，当Redis中的key
        String token = request.getHeader("token");
        String userId = JWT.decode(token).getAudience().get(0);
        //获取hdfs文件输出流,路径为user的id
        FSDataOutputStream fsDataOutputStream = fs.create(new Path("/course/"+userId+"/"+originalFilename));
        //本地文件输入流
        InputStream inputStream = file.getInputStream();
        IOUtils.copy(inputStream, fsDataOutputStream);
        //关闭流
        inputStream.close();
        fsDataOutputStream.close();
        //关闭hdfs连接
        close();
        int fileSize = (int) (file.getSize() / 1024 / 1024);

        //更新课程信息
        LambdaUpdateWrapper<Course> lqw = new LambdaUpdateWrapper<>();
        lqw.eq(Course::getFileName,originalFilename);
        lqw.eq(Course::getFileUserId,userId);
        lqw.eq(Course::getFileSize,fileSize);
        if (iCourseService.getOne(lqw)!=null){
           lqw.set(Course::getFileTime,DateUtil.now());
           iCourseService.update(lqw);
           return Result.success();
        }

        //保存课程信息
        Course course = new Course();
        course.setFileName(originalFilename); //文件名
        String[] split = originalFilename.split("\\.");
        course.setFileType(split[split.length-1]); //文件类型
        course.setFileSize(fileSize); //文件大小
        course.setFileUserId(userId); //上传用户id
        course.setFileTime(DateUtil.now()); //上传时间
        iCourseService.save(course);

        return Result.success();
    }
    /*
        分页查询
     */
    @GetMapping("/page")
    public Result page(@RequestParam Integer pageNum, @RequestParam Integer pageSize, HttpServletRequest request){
        String userID = request.getHeader("token");
        userID = JWT.decode(userID).getAudience().get(0);

        LambdaQueryWrapper<Course> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Course::getFileUserId,userID);
        queryWrapper.orderByDesc(Course::getId);
        Page<Course> page = iCourseService.page(new Page<>(pageNum, pageSize), queryWrapper);
        return  Result.success(page);

    }
    /*
    下载文件
     */
    @GetMapping("/download/{fileName}")
    public Result downloadFile(@PathVariable String fileName,HttpServletRequest request) throws Exception {
        //连接hdfs
        initHDFS();
        String token = request.getHeader("token");
        String userId = JWT.decode(token).getAudience().get(0);
        Path src = new Path(COURSE_KEY+userId+"/"+fileName);
        Path dfs = new Path("D:/HDFS/"+fileName);
        fs.copyToLocalFile(src, dfs);
        //关闭hdfs连接
        close();
        return Result.success();
    }
    /*
    删除文件
     */
    @DeleteMapping("/delete/{fileName}")
    public Result deleteFile(@PathVariable String fileName,HttpServletRequest request) throws Exception {
        //连接hdfs
        initHDFS();
        String token = request.getHeader("token");
        String userId = JWT.decode(token).getAudience().get(0);
        Path src = new Path(COURSE_KEY+userId+"/"+fileName);
        fs.delete(src, true);
        //关闭hdfs连接
        close();
        LambdaQueryWrapper<Course> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Course::getFileName,fileName).eq(Course::getFileUserId,userId);
        Course one = iCourseService.getOne(lqw);
        iCourseService.remove(lqw);

        //删除课程用户关联信息
        LambdaQueryWrapper<CourseUser> lqw1 = new LambdaQueryWrapper<>();
        lqw1.eq(CourseUser::getCourseId,one.getId());
        iCourseUserService.remove(lqw1);
        return Result.success();
    }

    //连接hdfs
    private void initHDFS() throws IOException {
        // 配置连接
        Configuration conf = new Configuration();
        // 在 core-site.xml 文件中
        conf.set("fs.defaultFS", "hdfs://localhost:9000");
        // 设置文件复制次数
        conf.set("dfs.replication", "2");
        fs = FileSystem.get(conf);
    }

    //关闭hdfs连接
    private void close() throws Exception {
        if (fs != null) {
            fs.close();
        }
    }
}
